﻿let gameDao = require("./../dao/gameDao");
let gameConfig = require("./../config/gameConfig");
let redis_laba_win_pool = require("./../../util/redis_laba_win_pool");
let configDao = require("./../dao/configDao");
const GameInfo = require("./game");
let log = require("./../../util/loginfo").getInstand;

arithmetic = function (_idx) {
	//相关属性
	//调试是否显示相关数据
	let debug = false;

	//可选择倍数
	let betCountObj = {};
	betCountObj[1] = 1;
	betCountObj[2] = 2;
	betCountObj[5] = 3;
	betCountObj[10] = 4;
	betCountObj[20] = 5;
	betCountObj[50] = 6;
	betCountObj[100] = 7;
	let betCount = [1, 10, 20, 50, 100];

	//外部控制倍率
	this.controlBet = 0.98;
	//超级大奖占成
	this.poolBet = 0.01;

	this._testMax = 0;

	//分数数组
	this.scoreArr = {};

	//虚拟奖池
	this.virtual_score_pool = 1000000;
	//实际奖池
	this.score_pool = [];

	//========================================
	//水位
	this.nGamblingWaterLevelGold = 0;
	//库存
	this.nGamblingBalanceGold = 0;
	//奖池
	this.nGamblingWinPool = 0;
	//大奖幸运等级
	this.nGamblingBigWinLevel = [];
	//大奖幸运概率
	this.nGamblingBigWinLuck = [];

	this.printPool = function () {
		for (var i = 0; i < betCount.length; ++i) {
			log.info("i:" + i + "-" + this.score_pool[i]);
		}
	};

	//获得实际奖池
	this.getScorePool = function (_betIdx) {
		if (this.score_pool[_betIdx]) {
			this.printPool();
			return this.score_pool[_betIdx];
		} else {
			//this.printPool();
			return 0;
		}

	};

	this.getScorePoolList = function () {
		return this.score_pool;
	};

	this.getScorePoolListLength = function () {
		return betCount.length;
	};

	this.getScoreId = function () {
		return betCount;
	};


	this.getGamblingBalanceGold = function () {
		//获取库存 奖池   数据库同步使用
		var dict = {
			nGamblingBalanceGold: this.nGamblingBalanceGold,
			nGamblingWinPool: this.nGamblingWinPool
		};

		return dict;

	};
	this.addGamblingBalanceGold = function (Gold, Pool) {
		//添加库存 奖池   数据库同步使用
		this.nGamblingBalanceGold += parseInt(Gold);
		this.nGamblingWinPool += parseInt(Pool);
		log.info("添加 " + Gold + " 到库存, 最新库存值为 " + this.nGamblingBalanceGold);
		log.info("添加 " + Pool + " 到奖池, 最新奖池值为 " + this.nGamblingWinPool);

		//redis存储奖池
		redis_laba_win_pool.redis_win_pool_incrby(parseInt(Pool))
	};
	this.subGamblingBalanceGold = function (Gold, Pool) {
		//减少库存   奖池 数据库同步使用
		//this.nGamblingBalanceGold-= parseInt(Gold);
		this.nGamblingWinPool -= parseInt(Pool);
		log.info("减少 " + Gold + " 库存, 最新库存值为 " + this.nGamblingBalanceGold);
		log.info("减少 " + Pool + " 奖池, 最新奖池值为 " + this.nGamblingWinPool);

		//redis奖池
		redis_laba_win_pool.redis_win_pool_decrby(parseInt(Pool))
	};
	this.getGamblingBalanceLevelBigWin = function () {
		//获取库存  水位 奖池 幸运值   判断中奖使用
		let value = {
			nGamblingWaterLevelGold: this.nGamblingWaterLevelGold,
			nGamblingBalanceGold: this.nGamblingBalanceGold,
			nGamblingWinPool: this.nGamblingWinPool,
			nGamblingBigWinLevel: this.nGamblingBigWinLevel,
			nGamblingBigWinLuck: this.nGamblingBigWinLuck
		};
		return value;
	};

	//添加实际奖池
	this.addScorePool = function (_betIdx, _socre) {
		if (this.score_pool[_betIdx]) {
			this.score_pool[_betIdx] += parseInt(_socre);
		} else {
			this.score_pool[_betIdx] = 0;
			this.score_pool[_betIdx] += parseInt(_socre);
		}

		this.printPool();
	};

	//减少奖池
	this.subScorePool = function (_betIdx) {
		if (this.score_pool[_betIdx]) {
			this.score_pool[_betIdx] -= this.subValue;
		} else {
			this.score_pool[_betIdx] = 0;
		}
		this.printPool();
	};

	this.getAllcaishenValue = function () {
		//获得全财神的值
		return this.subValue;
	};

	//获得奖池
	this.getVirtualScorePool = function () {
		//var result = {virtual_score_pool:this.virtual_score_pool,score_pool}
		return this.virtual_score_pool;
	};

	//添加奖池
	this.addVirtualScorePool = function (score_bet) {
		this.virtual_score_pool += parseInt(score_bet);
	};

	//减少虚拟奖池
	this.subVirtualScorePool = function (score_bet, flag) {
		this.subValue = Math.floor((this.virtual_score_pool / 100 * score_bet * 0.9));
		if (flag) {
			this.virtual_score_pool -= this.subValue;
		} else {
			if (this.virtual_score_pool - this.subValue > 900000 || this.virtual_score_pool > 2000000) {
				this.virtual_score_pool -= this.subValue;
			}
		}
	};

	this.init = function () {
		//初始化水位和库存
		this.initGamblingGame();
	};

	//获得当前概率
	this.getBet = function () {
		return this.controlBet;
	};

	//设置概率
	this.setBet = function (_bet) {
		this.controlBet = _bet;
	};

	this.CheckBet = function (_betIdx) {
		return betCount[_betIdx];
	};

	this.Check_bet_dict = function (bet_dict) {
		//检查下注字典
		if (bet_dict.nBetItem == undefined || bet_dict.nBetItem == null) {
			log.info("缺少字段nBetItem");
			return false;
		}
		if (bet_dict.nBet == undefined || bet_dict.nBet == null || bet_dict.nBet == 0) {
			log.info("缺少字段nBet");
			return false;
		}
		return true;
	};

	//=================================================================================================
	this.initGamblingGame = function () {
		var self = this;
		gameDao.getGamblingGame(function (Result) {

			self.nGamblingWaterLevelGold = Result[0].nGamblingWaterLevelGold;  //水位
			self.nGamblingBalanceGold = Result[0].nGamblingBalanceGold;      //库存
			self.nGamblingWinPool = Result[0].nGamblingWinPool;      //奖池
			self.nGamblingBigWinLevel = Result[0].nGamblingBigWinLevel.split(',').map(Number);  //大奖幸运等级
			self.nGamblingBigWinLuck = Result[0].nGamblingBigWinLuck.split(',').map(Number);    //大奖幸运概率

			//redis存储奖池
			redis_laba_win_pool.redis_win_pool_incrby(self.nGamblingWinPool);

			log.info("读取采池数据完毕!");
			log.info("水位:" + self.nGamblingWaterLevelGold);
			log.info("库存:" + self.nGamblingBalanceGold);
			log.info("奖池:" + self.nGamblingWinPool);
			log.info("大奖幸运等级:" + self.nGamblingBigWinLevel);
			log.info("大奖幸运概率:" + self.nGamblingBigWinLuck);
		})


	};

	this.gameProcessor = function (game_odd, betInfo_list, nGamblingWinPool, RewardHorseNo, isCtrlRoundNO, roundNO) {
		log.info("~~~~~~~~~~~~~~~ nGamblingWinPool " + nGamblingWinPool + " game_odd " + game_odd);

		//# 初始化下注数组
		let all_bet_list = [0, 0, 0, 0, 0, 0, 0, 0]; //# 普通下注数组
		// ZZZ-20230511,
		let all_bet_sort = [[0,0], [1,0], [2,0], [3,0], [4,0], [5,0], [6,0], [7,0]]; // 排序下注数组
		let pay_bet_list = []; // 能够赔付的数组
		let bet_all = 0; // 总共下注
		//# 遍历所有下注 计算所有花色下注额度
		for (let i in betInfo_list) {
			let betInfo = betInfo_list[i];
			let idx = parseInt(betInfo["nBetItem"]); //马号
			let bet = parseInt(betInfo["nBet"]); //投注

			bet_all += bet;
			all_bet_list[idx] += bet;
			all_bet_sort[idx][1] += (bet * game_odd[idx]);
		}
		// 按照赔付金额从小到大排序
		all_bet_sort.sort(function(a, b) {
			return (a[1] > b[1]) ? 1 : -1;
		});
		for (let i in all_bet_sort) {
			let idx = all_bet_sort[i][0];
			let pay = all_bet_sort[i][1];
			let bet = all_bet_list[idx];

			if (pay <= 0 || pay <= (nGamblingWinPool/100)) { // 金额占比很小
				pay_bet_list.push(idx);
			} else {
				if (pay <= (nGamblingWinPool/10)) { // 奖金要留有余量
					if ((bet / bet_all) <= 0.85) { // 消除峰值
						pay_bet_list.push(idx);
						log.info("idx=" + idx + ", <= 0.85, pushed");
					}
				} else {
					if (Math.abs(pay - bet_all) <= (bet_all*0.15)) { // 有差不多可以对冲的数额
						pay_bet_list.push(idx);
						log.info("idx=" + idx + ", <= 0.15, pushed");
					}
				}
			}
		}
		log.info("~~~~~~~~~~~~~~~ gameProcessor all_bet_sort=" + JSON.stringify(all_bet_sort));
		log.info("~~~~~~~~~~~~~~~ gameProcessor pay_bet_list=" + JSON.stringify(pay_bet_list));

		let win_card_index, win_card, win_list;
		if (RewardHorseNo >= 0 && RewardHorseNo < 8 && isCtrlRoundNO) { //是否触发风控
			win_card = RewardHorseNo;
			win_card_index = RewardHorseNo;

			configDao.clearHorseNo(roundNO, function (state) {
				if (state) {
					log.info("clear Horse config success! round no " + roundNO);
				}
			});

			log.info("trigger risk control event win card " + win_card + " win card index " + win_card_index);
		} else {
			// ZZZ-20230511, 赔付判断
			if (pay_bet_list.length <= 1) { // 都不够赔付或仅有一个，选最小的
				win_card_index = all_bet_sort[0][0];
				win_card = win_card_index;
				log.info("~~~~~~~~~~~~~~~ 都不够赔付，选最小的，马号 = " + win_card_index + ", 金额 = " + all_bet_sort[0][1]);
			} else {
				// 部分(或全部)够赔付，在这里面随机选
				win_card_index = RandomNumBoth(0, pay_bet_list.length-1);
				win_card_index = pay_bet_list[win_card_index];
				win_card = win_card_index;
			}
		}
		// 建立排名
		win_list = [0, 1, 2, 3, 4, 5, 6, 7];
		win_list.splice(0, 1);
		win_list = win_list.sort(randomsort);
		win_list.splice(win_card_index, 0, 0);
		log.info(" win_card " + win_card + " win_card_index " + win_card_index + " win list " + win_list);

		//算账
		//# 给中奖的人算钱
		let bet_userlist = {};
		let win_userlist = {};
		for (let i in betInfo_list) {
			let betInfo = betInfo_list[i];
			log.info("bet info " + betInfo);
			if (!bet_userlist[betInfo["userId"]]) {
				bet_userlist[betInfo["userId"]] = 0;
			}
			if (!win_userlist[betInfo["userId"]]) {
				win_userlist[betInfo["userId"]] = 0;
			}
			bet_userlist[betInfo["userId"]] += betInfo["nBet"];
			log.info("user bet list user " + betInfo["userId"] + " item " + betInfo["nBetItem"] + " bet " + bet_userlist[betInfo["userId"]]);
			if (betInfo["nBetItem"] == win_card_index) {  //普通下注
				win_userlist[betInfo["userId"]] += betInfo["nBet"] * game_odd[win_card_index];
				log.info("user win list user " + betInfo["userId"] + " win index " + win_card_index + " win " + win_userlist[betInfo["userId"]]);
			}
		}

		//# 将计算后的下注结果放到结果中，为外层赋值使用

		//开奖算法
		let dictAnalyseResults = {};
		dictAnalyseResults["betInfo"] = betInfo_list;
		dictAnalyseResults["win_card_index"] = win_card_index; //# 获胜索引
		dictAnalyseResults["win_card"] = win_card;  //# 获胜号码
		dictAnalyseResults["win_list"] = win_list;  //# 赛马排序
		dictAnalyseResults["bet_user_list"] = bet_userlist;  //# 下注字典
		dictAnalyseResults["win_user_list"] = win_userlist; //# 赢钱字典

		return dictAnalyseResults;
	};

	this.init();
};


function RandomNumBoth(Min, Max) {
	//生成指定范围内随机整数
	var Range = Max - Min;
	var Rand = Math.random();
	var num = Min + Math.round(Rand * Range); //四舍五入
	return num;
}

function randomsort(a, b) {
	//数组随机排序
	//使用方法
	//arr.sort(randomsort)
	return Math.random() > .5 ? -1 : 1; //通过随机产生0到1的数，然后判断是否大于0.5从而影响排序，产生随机性的效果。
}

module.exports = arithmetic;